<!DOCTYPE html>

<!--
  Google HTML5 slide template

  Authors: Luke Mahé (code)
           Marcin Wichary (code and design)
           
           Dominic Mazzoni (browser compatibility)
           Charles Chen (ChromeVox support)

  URL: http://code.google.com/p/html5slides/
-->

<html>
<head>
<title>Presentation</title>
<meta charset='utf-8'>
<script src='../slides.js'></script>
<style>
.slides.template-inftel > article:not(.nobackground):not(.biglogo) {
	background: url(images/inftel-logo.png) 560px 605px no-repeat;
	background-color: white;
}
</style>
</head>


<body style='display: none'>
<img style='display:none' src='images/inftel-logo.png'>
<section class='slides layout-regular template-inftel'> 
  
<article>
<h1>
<span style="font-size: 55px">Telecare Management System</span><br> 
<span style="font-size: 50%">
	Sistema de gestión de teleasistencia. Interfaz Android.
</span>
</h1>
<p>
	Agustín M. Pereña García<br>
	Miguel Angel Quero Marín<br>
	Miguel Pintor Moral<br>
	Cristian Jiménez Salvatierra<br>
	Ignacio Baca Moreno-Torres<br> 
	Marzo 2012
</p>
</article>

<!-- --------------------------------- Introduccion -------------------------------------------- -->

<article class='fill'>
<h3> Introducción y planteamiento del problema </h3>
<p> <img src='images/android-electro.png'> </p>
<!-- <div class='source'>Por: Alguien</div> -->
</article>

<article>
<h3>TMS en terminales moviles: Planteamiento</h3>
<ul style="font-size:90%">
<li>En esta practica nos planteamos el hecho de extender el	trabajo realizada en otros modulos a un terminal movil.</li>
<li>En nuestro caso nos propusimos conservar todas las funcionalidades que ya poseia, y en caso de poder, ampliarlas.</li>
<li>Algunas de las funcionalidades de nuestra aplicacion quedaban obsoletas (login), otras requerian de un complicado proceso para su implementacion el el terminal (mapas).</li>
<li>Tambien veiamos interesantes nuevas funcionalidades que	podrian dar mas valor a nuestra aplicacion (vallas).</li>
<li>Todo esto orientado a aplicar y afianzar los conceptos vistos en clase.</li>
</ul>
</article>

<article class="nobackground">
<h3>TMS en terminales moviles: Resolucion</h3>
<ul style="font-size:95%; line-height: 100%">
<li>Dada la buena experiencia con las metodologias de desarrollo del modulo anterior nos planteamos utilizar Scrum en	este proyecto y distribuir el trabajo en tareas en lugar de la distribucion por capas. Para esto hicimos uso de herramientas como Trello,...</li>
<li>De cara a las funcionalidades desechamos el uso de la pantalla de login, ya que consideramos el terminal movil como algo personal.</li>
<li>En cuanto a mostrar mapas de las alertas consideramos que para un usuario no era imprescindible ver la localizacion desde	donde se manda una alerta, de echo ni siquiera necesario.</li>
<li>En cuanto al protocolo hemos podido reciclar gran parte del	codigo usado otros modulos.</li>
<li>Por ultimo decir que hemos desarrollado prototipos que se han ido refinando a lo largo de las diferentes iteraciones.</li>
</ul>
</article>

<article class="nobackground">
<h3>Contenido de la presentación</h3>
<ul style="font-size:95%; line-height: 100%">
<li>Widgets y Activities
<li>Protocolo PaSOS y Servicios Android
<li>Sensores y Alarmas
<li>Preferencias y Diseño
<li>Localización e Interfaces Avanzadas
</ul>
<p>Terminando con conclusiones y preguntas
</article>

<!-- --------------------------------- Widget & Activity --------------------------------------- -->

<article class='fill'>
<h3>Widgets y Activities</h3>
<p>
<img src='images/android-dude.jpg'>
</p>
<div class='source'>Por: Cristian Jimenez</div>
</article>

<article>
<h3>
TmsActivity<br>
</h3>
<p>
Es el Activity principal de nuestra aplicacion.<br>Controla un boton para el envio de alertas.<br>Gestiona su propio Menu que	permite al usuario navegar entre los actitvities.<br>
</p>
<br>
<h3>
PreferencesActivity<br>
</h3>
<p>
Es el Activity encargado de gestionar los diferentes parametros	configurables de nuestra aplicacion.<br> Mas en concreto nos permite especificar: 
<span style="font-size: 25px">
<ul style="margin-top:5px">
<li>Variables que definen la ruta donde se aloja el servidor.</li>
<li>Numero de telefono del terminal.</li>
</ul>
</span> 
Todos estos datos son almacenados en las preferencias de la	aplicacion.<br>
</p>
</article>

<article>
<h3>
FencesActivity<br>
</h3>
<p>
Nos permite asignar "vallas", o zonas alrededor de un punto con un radio determinado.<br>Permite asignar acciones al entrar dentro de estas "vallas".<br> Este activity tambien gestiona su propio	menu.
</p>
<br>
<h3>
AboutActivity<br>
</h3>
<p>Carga una pantalla de creditos.</p>
</article>
<article>
<h3>
Widget<br>
</h3>
<p style="font-size:80%">
Pequeño Widget cuyo unico elemento es un boton. Este boton lanza alarmas de usuario, con el
mismo funcionamiento que la propia	aplicacion. La ventaja es que con un solo dos clicks puedes 
mandar una alerta. Las claves del widget: 
<ul style="margin-top:5px">
<li>Obtener el ID del widget:
<pre style="margin:5px 0 0 0">
Intent intentOrigen = getIntent();
Bundle params = intentOrigen.getExtras();
widgetId = params.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);</pre>
<li>Lanzar adecuadamente un activity:
<pre style="margin-top:5px">
PendingIntent pendingIntent = PendingIntent.getActivity(context,
widgetId, new Intent(context, aleluya.class),
PendingIntent.FLAG_UPDATE_CURRENT);
controles.setOnClickPendingIntent(R.id.BtnActualizar, pendingIntent);</pre>
</ul>
</p>
</article>

<!-- --------------------------------- Protocolo y Servicios ----------------------------------- -->

<article class='fill'>
<h3> Protocolo PaSOS y Servicios Android </h3>
<p> <img src='images/android-metal.png'> </p>
<div class='source'>Por: Miguel Angel Quero Marín</div>
</article>

<article class="nobackground">
<h3>Mensaje PASOS</h3>
<p> <img src='images/pasos.png' class="centered" style="width:120%"> </p>
</article>

<article>
<h3>Patrón builder</h3>
<ul>
<li>Abstrae el proceso de creación de un objeto complejo,
centralizando dicho proceso en un único punto.</li>
<li> Permite que el mismo proceso de construcción pueda crear
representaciones diferentes del mismo objeto.</li>
<li>Permite controlar la construcción de un producto paso a paso.</li>
<li>Sólo cuando el producto está acabado se instancia el objeto.</li>
</ul>
<pre style='margin-top:0'>
PasosMessage message = buildTechnicalAlarm()
  .location(latitude, longitude)
  .cause("tracking: seguimiento pasivo");
  .build();
</pre>
</article>

<article>
<h3>Envio de tramas al servidor</h3>
<p>Problema: un Service se ejecuta por defecto en el mismo thread que
lo llama, quedando este bloqueado.</p>
<br />
<p>Solución: usar Intent Services.</p>
<ul>
<li>IntentService es una subclase de Service.
<li>Una instancia de IntentService se ejecuta en su propio thread y
gestiona peticiones asincronas.</li>
<li>Para usarlo solo es necesario crear una clase que herede de
IntentService e implemente el método onHandleIntent(Intent).</li>
</ul>
</article>

<article>
<h3>Ciclo de vida de un Intent Service</h3>
<ul>
<li>El cliente manda peticiones mediante startService(Intent).</li>
<li>El servicio se ejecuta si es necesario, y maneja cada petición en
un sólo hilo, de una en una.</li>
<li>Cuando la cola de peticiones está vacía, el mismo se muere.</li>
</ul>
<p>Ejemplo de uso</p>
<pre style='margin-top:15px'>
       Intent sendService = new Intent(this,
SendPasosMessageIntentService.class);
       sendService.putExtra(TmsConstants.EXTRA_KEY_MESSAGE_CONTENT,
message.toString());
       startService(sendService);
</pre>
</article>

<!-- --------------------------------- Sensores y Alarms --------------------------------------- -->

<article class='fill'>
<h3> Sensores y Alarmas </h3>
<p> <img src='images/android-corner.jpg'> </p>
<div class='source'>Por: Miguel Pintor</div>
</article>

<article>
<h3>Objetivos marcados</h3>
<p><b>Objetivos</b></p>
<ul>
<li>Alerta por batería baja.</li>
<li>Alerta periódica con el nivel de batería y la temperatura.</li>
</ul>
<br/>
<div class="build">
<p><b>Soluciones</b></p>
<ul>
<li>Uso de BroadcastReceiver ligado a android.intent.action.BATTERY_LOW, evitando un polling continuo de la batería.</li>
<li> Uso del AlarmManager (acciones periódicas programadas). Emulación del sensor de temperatura durante el desarrollo.</li>
</ul>
</div>
</article>

<article>
<h3>Funcionamiento</h3>
<iframe width="560" height="315" src="http://www.youtube.com/embed/3k-e4fu7DCU?rel=0" frameborder="0" allowfullscreen></iframe>
</article>

<article>
<h3>Herramientas</h3>
<div style="font-size: 80%">
<ul>
<li>Telnet  para cambios relacionados con la batería </li>
<p>Instalación en Windows 7</p>
<ol>
<li>Panel de control -> Programas -> Programas y características</li>
<li>Marcar Activar o desactivar características de windows -> Telnet</li>
<li>Abir una consola (cmd):
<br/>c:\ > telnet localhost 5554 
<br/>Ejemplos:
<br/>[Desenchufar ac]  c:\ > power ac off
<br/>[Cambiar estado] c:\ > power status not-charging
<br/>[Cambiar nivel a 80%] c:\ > power capacity 80 
</li>
</ol>
<li>Sensorsimulator-1.1.1 para la temperatura:<br/>
http://www.androidconnect.com.ar/2011/08/usando-los-sensores.html</li>
</ul>
</div>
</article>

<article>
<h3>Demo</h3>
<iframe width="420" height="315" src="http://www.youtube.com/embed/V3J6uVilW3Y?rel=0" frameborder="0" allowfullscreen></iframe>
</article>

<!-- --------------------------------- Preferencias y Diseño ----------------------------------- -->

<article class='fill'>
<h3> Preferencias y Diseño </h3>
<p> <img src='images/android-black.jpg'> </p>
<div class='source'>Por: Agustín M. Pereña García</div>
</article>

<article class="nobackground">
<h3>Preferencias</h3>
<p>Diferentes formas de gestionar las preferencias en Android</p>
<ul>
<li>
<p style="color:green">Preferencias compartidas (SharedPreferences)</p>
<p>Fichero de configuración:</p>
<pre>
data/data/org.inftel.tms.mobile/shared_prefs/
org.inftel.tms.mobile_preferences.xml
</pre>
<p>Acceso a las preferencias</p>
<pre>prefs = getSharedPreferences(TmsConstants.SHARED_PREFERENCE_FILE, 
									Context.MODE_PRIVATE);
prefsEditor = prefs.edit();
prefsEditor.putBoolean(TmsConstants.SP_KEY_RUN_ONCE, true);
prefsEditor.commit();
</pre>
</li>
</ul>
</article>

<article class="nobackground">
<h3>Preferencias</h3>
<ul>
<li>
<p style="color:green">Pantalla prefererencias mediante xml</p>
</li>
<img src="images/preferences.png" style="width: 40%; float:right"/>
<p>Tipos de Elementos:</p>
<ul>
<li><b>CheckBoxPreference</b></li>
<li><b>EditTextPreference</b></li>
<li><b>ListPreference</b></li>
<li><b>MultiSelectListPreference</b></li>
</ul>
<p>Clasificación por categorías</p>
</ul>
</article>



<article>
<h3>Preferencias</h3>
<ul>
<li>
<p style="color:gray">Definición del pantalla en /xml/preferences.xml</p>
<pre style="font-size:55%">
&lt;PreferenceScreen xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot; &gt;
    &lt;PreferenceCategory android:title=&quot;@string/phone_preferences&quot; &gt;
        &lt;EditTextPreference
        	android:defaultValue=&quot;@string/default_phone_number_preference&quot;
            android:dialogTitle=&quot;@string/dialog_title_phone_number_preference&quot;
            android:key=&quot;phone_number_preference&quot;
            android:summary=&quot;@string/sumary_phone_number_preference&quot;
            android:title=&quot;@string/title_phone_number_preference&quot; /&gt;
    &lt;/PreferenceCategory&gt;
&lt;/PreferenceScreen&gt;
</pre>
</article>


<article>
<h3>Preferencias</h3>
<ul>
<li>
<p style="color:gray">Creación de la pantalla (PreferenceActivity)</p>
<pre>
public class PreferencesActivity extends PreferenceActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
    }
}
</pre>
</li>
<li>
<p>Declaración en el fichero AndroidManifest.xml</p>
<pre>
&lt;activity android:name=&quot;.ui.PreferencesActivity&quot; &gt;
&lt;/activity&gt;
</pre>
</li>
</ul>
</article>



<article class="nobackground">
<h3>Preferencias</h3>

<p>Consulta de preferencias</p>
<p>
<img src="images/preferences_2.png" style="width: 40%; float:right; margin-right:-20px; margin-left:15px "/>
</p>

<pre style="font-size:45%;"> 
SharedPreferences prefs = PreferenceManager
                             .getDefaultSharedPreferences(this);
String host = prefs.getString(TmsConstants.KEY_IP_PREFERENCE, "");
</pre>
</article>



<article class="nobackground">
<h3>Diseño</h3>

<p style="color:green">Activity "Acerca de..."</p>
<img src="images/about.png" style="width: 40%; float:right"/>

<p>Poner en práctica:</p>
<ul>
<li>Utilización Efectos: transparencias, sombras,...</li>
<li>Separación de la descripción de pantalla de los estilos.</li>
<ul>
<li>layout/about.xml: descripción de la pantalla</li>
<li>values/style.xml: definición de estilos comunes</li>
</ul>
</ul>
</article>


<article class="nobackground">
<h3>Diseño</h3>
<ul>
<li>
<p style="color:gray">Declaración de componentes en /layout/about.xml</p>
<pre>
&lt;TextView
style=&quot;@style/description&quot;
android:text=&quot;@string/desc_agumpg&quot; /&gt;
</pre>
<p style="color:gray">Declaración de estilos en /values/style.xml</p>
<pre style="font-size:55%">
    &lt;style name=&quot;description&quot; parent=&quot;@android:style/TextAppearance.Small&quot;&gt;
        &lt;item name=&quot;android:textSize&quot;&gt;15sp&lt;/item&gt;
        &lt;item name=&quot;android:layout_height&quot;&gt;wrap_content&lt;/item&gt;
        &lt;item name=&quot;android:layout_width&quot;&gt;fill_parent&lt;/item&gt;
        &lt;item name=&quot;android:gravity&quot;&gt;center_vertical|center_horizontal&lt;/item&gt;
        &lt;item name=&quot;android:textColor&quot;&gt;#BCBCBC&lt;/item&gt;
        &lt;item name=&quot;android:layout_marginTop&quot;&gt;5px&lt;/item&gt;
    &lt;/style&gt;
</pre>
</li>
</ul>
</article>



<article class="nobackground">
<h3>Diseño</h3>
<p style="color:green">Botón Pantalla principal</p>
<img src="images/efecto_push_release.png" style="width: 40%; float:right"/>
<p>Definición del selector:</p>
<pre style="font-size:45%">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
   &lt;selector 
   xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&gt;
   &lt;item android:drawable=&quot;@drawable/btn_push&quot;
          android:state_pressed=&quot;true&quot; /&gt;
   &lt;item android:drawable=&quot;@drawable/btn_release&quot;
          android:state_pressed=&quot;false&quot; /&gt;
&lt;/selector&gt;
</pre>

</article>



<article class="nobackground">
<h3>Diseño</h3>
<p style="color:green">Botón Pantalla principal</p>
<img src="images/efecto_push_release.png" style="width: 40%; float:right"/>
<ul>

<li><p>Inclusión del selector e imágenes de botones en /drawable</p></li>
<li><p>Enlazar selector al ImageView definido en el layout</p></li>
<pre style="font-size:45%">
&lt;ImageButton
    android:id=&quot;@+id/buttonUserAlarm&quot;
    android:contentDescription=&quot;@string/send_alert&quot;
    android:scaleType=&quot;center&quot;
    android:src=&quot;@drawable/selector_btn_user_alarm&quot; /&gt;
</pre>
<li><b>Nota: </b>no olvidar definir contentDescription para accesibilidad</li>
</ul>
</article>



<article class="nobackground">
<h3>Diseño</h3>
<p style="color:green">Icono de aplicación</p>
<img src="images/ic_launcher.png" style="width: 40%; float:right"/>
<p>Recursos en Android-Developers</p>
<ul>
<li>Guías y mejores prácticas de diseño</li>
<li>Templates para creación de iconos</li>
<li>Heramientas para optimización .png (i.e. OptiPNG, ImageOptim,...)</li>
<li>Enlace a Web específica para diseñadores (recursos, recomendaciones,...)</li>
<img src="images/ic_launcher_size.png" style="width: 95%;"/>
</ul>
</article>




<!-- --------------------------------- Localizacion y Fragments -------------------------------- -->

<article class='fill'>
<h3> Localización e Interfaces Avanzadas </h3>
<p> <img src='images/android-pizarra.jpg'> </p>
<div class='source'>Por: Ignacio Baca Moreno-Torres</div>
</article>

<article>
<h3>La fragmentación</h3>
<p>Android cambia de versión rápido</p>
<p>En el 2011 sacó 15 versiones diferentes, incluyendo mejoras en las ramas 2.X, 3.X y 4.X.</p>
<p>Opciones
<ul style="margin-top:10px">
<li>Programar en una versión antigua
<br><span style="color:darkred">reinventar la rueda, mala idea</span>
<li>Escribir código diferente para cada versión
<br><span style="color:darkred">complejo, pero mejor que reinventar</span>
<li>Usar librerías que mantienen compatibilidad
<br><code>android-compatibility-package-v4</code>
<br><span style="color:green">menos complejo, menos reinvención. Me gusta!</span>
</ul>
</article>

<article>
<h3>Localización: Tracking</h3>
<p>El tracking es critico en el diseño de la app</p>
<ul>
<li>Consume energía
<li>Consume comunicación (red)
<li>Puede variar la precisión
<li>Puede variar la disponibilidad
</ul>
<p>Elegir entre estos criterios e integrar las herramientas nativas es "complejo"</p>
</article>

<article>
<h3>¿Porque es "complejo"?</h3>
<img src="http://android10.org/images/stories/development/android_location_providers_03.jpg"
	 style="float: right" />
<ul>
<li>Muchos proveedores: GPS, AGPS, CellID, Wifi MACID, Mocked, etc.
<li>Los proveedores cambian en tiempo de ejecución
<li>Cada proveedor tiene ventajas: precisión, tiempo de respuesta
<li>O desventajas: consumo de energía, poca cobertura, etc.
<li>El usuario puede deshabilitar algunos proveedores
<li>Cada versión android aporta nuevas herramientas
</ul>
</article>

<article>
<h3>Localización: Que criterio tomamos</h3>

<ul>
<li>
<p style="color:green">Subscripción antes que timmer
<p>El sistema solo notifica cuando hay un cambio
<p><b>Ventaja: </b>Menor uso de recursos
<p><b>Problema: </b>Puede no estar disponible
<li>
<p style="color:green">Localización pasiva mejor que activa
<p><b>Ventaja: </b>No activa localización (encender GPS o comunicación red)
<p><b>Problema: </b>Puede pasar demasiado tiempo
<li>
<p style="color:green">Limite de tiempo y distancia
</article>

<article>
<h3>Localización: Por subscripción 1/2</h3>
<p>Pueden existir un numero desconocido de proveedores</p>
<p>Se debe escoger la mejor localización gastando la menor cantidad de recursos</p>
<p><b>Gingerbread 2.3</b> (permite definir criterios)</p>
<pre>locationManager.requestLocationUpdates(
  minTime, minDistance, criteria, pendingIntent);</pre>
<p><b>Froyo 2.2</b> (permite definir suscripción pasiva)</p>
<pre>locationManager.requestLocationUpdates
  (PASSIVE_PROVIDER,MAX_TIME, MAX_DISTANCE, pendingIntent);</pre>
</article>

<article>
<h3>Localización: Por subscripción 2/2</h3>
<p><b>Legacy &lt;=2.1</b> (requiere usar timmer)</p>
<p>Suscripción Activa, criteria se usa de forma manual
<pre style="margin-top:10px;margin-bottom:-10px">
String provider = locationManager.getBestProvider(criteria, true);
if (provider != null) {
  locationManager.requestLocationUpdates(provider, 
  minTime, minDistance, pendingIntent); 
}
</pre>
<p><span style="color:darkred">Se debe monitorizar que no se apage el proveedor</span></p>
<p>Suscripción Pasiva, requiere uso de AlarmManager
<pre style="margin-top:10px">
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, 
  System.currentTimeMillis()+PlacesConstants.MAX_TIME, 
  PlacesConstants.MAX_TIME, pendingIntent);
</pre>
</article>

<article>
<h3>Localización: Por subscripción y se apaga!</h3>
<p><span style="color:darkred">Que ocurre si se apaga</span>
<br>Comprobar que sigue activo en cada notificación</p>
<pre style="margin-top:10px;margin-bottom:-10px">
if (intent.hasExtra(providerEnabledKey)) {
  if (!intent.getBooleanExtra(providerEnabledKey, true)) {
    Intent providerDisabledIntent = new Intent(
      PlacesConstants.ACTIVE_LOCATION_UPDATE_PROVIDER_DISABLED);
    context.sendBroadcast(providerDisabledIntent); } }
</pre>
<p><span style="color:darkred">Y si encienden un proveedor mejor</span></p>
<pre style="margin-top:10px">
// Register a receiver that listens for when a better provider than I'm using becomes available.
String bestProvider = locationManager.getBestProvider(criteria, false);
String bestAvailableProvider = locationManager.getBestProvider(criteria, true);
if (bestProvider != null && !bestProvider.equals(bestAvailableProvider)) {
  locationManager.requestLocationUpdates(bestProvider, 0, 0, bestInactiveLocationProviderListener, getMainLooper());
}
</pre>
</article>

<article>
<h3>Localización: Consultar localización</h3>
<pre>locationManager.getLastKnownLocation(provider);</pre>
<h4 style="color:darkred">Nooooo! ¿Que proveedor? ¿el resultado de cuando es?</h4>
<p>Dos criterios fundamentales
<ul style="margin-top:10px">
<li><b>Hora de la muestra</b>, no se quieren datos obsoletos
<li><b>Precisión de la muestra</b>, los datos demasiado imprecisos pueden no ser utiles
<li>Si se cumple un mínimo, queremos el dato más <b>actual</b> y más <b>preciso</b>
<li><em>No olvidar usar la menor cantidad de recursos!</em>
</article>

<article class="nobackground">
<h3>Localización: LastKnown o OneShot</h3>
<pre style="margin-top:15px">
for (String provider : matchingProviders) {
  Location location = locationManager.getLastKnownLocation(provider);
  if (location != null) {
    float accuracy = location.getAccuracy();
    long time = location.getTime();
    
    // ¿ Cumple los requisitos, y en tal caso, es mejor?
    if ((time > minTime && accuracy < bestAccuracy)) {
      bestResult = location; bestAccuracy = accuracy; bestTime = time;
    } else if (time < minTime && bestAccuracy == Float.MAX_VALUE && time > bestTime) {
      bestResult = location; bestTime = time;  
    } 
} }

// Si ninguno cumple requisitos, se solicita localización
if (locationListener != null && (bestTime < minTime || bestAccuracy > minDistance)) {
	IntentFilter locIntentFilter = new IntentFilter(SINGLE_LOCATION_UPDATE_ACTION);
	context.registerReceiver(singleUpdateReceiver, locIntentFilter);
	locationManager.requestSingleUpdate(criteria, singleUpatePI);
}
</pre>
</article>

<article>
<h3>Las interfaces de usuario</h3>
<p>Cuando se diseñan las interfaces es común cometer errores
<ul>
<li>Los datos mostrados estan en internet
<li>La interfaz se bloquea o da saltos
<li>Inventamos nuestros sistemas de sincronización
<br>Tanto locales como remotos
<li>Duplicamos activities para interfaces tablet
</ul>
</article>


<article class="nobackground">
<h3>Como hacerlo todo mal</h3>
<iframe src="http://www.youtube.com/embed/HBoRCXoPUvg" frameborder="0" allowfullscreen></iframe>
</article>

<article class="smaller nobackground">
<h3>StrictMode</h3>
<q style="font-size: 29px; margin: 10px 0 10px 0">
StrictMode is most commonly used to catch accidental disk or network access on the application's 
main thread, where UI operations are received and animations take place.</q>
<iframe style="height: 405px" src="http://developer.android.com/reference/android/os/StrictMode.html"></iframe>
</article>

<article>
<h3>El primer paso para no bloquear MainThread</h3>
<pre>
// This isn't directly affecting the UI, so put it on a worker thread.
final AsyncTask<Void, Void, Location> findLationTask = new AsyncTask<Void, Void, Location>() {
  @Override
  protected Location doInBackground(Void... params) {
  	 // Este proceso puede tardar tanto como quiera
     Location lastKnownLocation = lastLocationFinder.getLastBestLocation(
        TmsConstants.MAX_DISTANCE,
        System.currentTimeMillis() - TmsConstants.MAX_TIME);
     return lastKnownLocation;
  }

  protected void onPostExecute(Location result) {
    // Aqui se puede actualizar el IU tras obtener el resultado
  }
};
findLationTask.execute();
</pre>
</article>

<article>
<h3>Cursor y Loaders</h3>
<p>Dejar a la plataforma hacer su trabajo
<pre>
public class FenceListFragment 
    extends ListFragment 
    implements LoaderCallbacks&lt;Cursor&gt; {

  protected Cursor cursor = null;
  protected SimpleCursorAdapter adapter;

  @Override
  public void onActivityCreated(Bundle savedInstanceState) {
      super.onActivityCreated(savedInstanceState);

      adapter = new SimpleCursorAdapter(activity,android.R.layout.simple_list_item_1,cursor,new String[] {FencesContentProvider.KEY_NAME},new int[] {android.R.id.text1},0);
      // Allocate the adapter to the List displayed within this fragment.
      setListAdapter(adapter);
</pre>
</article>

<article>
<h3>Fragments</h3>
<div style="position:relative">
<br>
<img src="https://d339vfjsz5zott.cloudfront.net/Android-SDK-Fragments/MT-Fragments-Fig1.png" class="centered"/>
<div class="build" style="position:absolute;top:0;width:100%;">
<img src="https://d339vfjsz5zott.cloudfront.net/Android-SDK-Fragments/MT-Fragments-Fig2.png"  class="centered" style="padding-right: 11px;"/>
</div>
</div>
</article>

<article>
<h3>Compatibilidad</h3>
<p>Hemos usado recursos modernos como
<ul style="margin-top:10px">
<li>Passive y Active Location Request
<li>Location Criteria
<li>Cursor, Loaders y Fragments
<li>StrictManager
</ul>
<p style="color:green">¿Es compatible con los móviles que usamos?</p>
<ul class="build" style="margin-top:15px">
<li><code>ADP4</code> Samsung Galaxy Gingerbread
<li><code>ADP3</code> HTC Nexus One Gingerbread
<li><code>ADP2</code> HTC Magic Froyo
<li><code>ADP1</code> HTC Dream Enclair
</ul>
</article>

<!-- --------------------------------- dudas y gracias ----------------------------------------- -->

<article class='fill'>
<h3> Conclusiones y dudas </h3>
<p> <img src='images/android-darkblue.jpg'> </p>
</article>

<article>
<h3>Conclusiones</h3>
<ul>
<li style="color:darkred">Complejo y de camino entre C y Java
<li style="color:darkred">UI quizas demasiado compleja y poco acabada
<li style="color:darkred">SDK complejo y extenso
<li style="color:darkred">Fragmentación lo hace aún mas complejo
<li style="color:darkred"><span style="color:green">Mucha libertad</span> acompañada de implicaciones
<li  style="color:green">Parece tener gran potencial para un usuario experto
<li  style="color:green">Mucha documentación oficial, y aún más documentación de la comunidad
</ul>
</article>

<article>
<h3> Dudas </h3>
<p style='margin-top:0'>
<img style='width: 600px' src='images/questions.jpg' class="centered">
</p>
</article>

<article class='fill'>
<h3> Gracias! </h3>
<p> <img src='images/android-up.jpg'> </p>
</article>

</section>
</body>
</html>
